class CalculationUnit:
    # fixme xsj 少字段报错 area yeaindvqu1r1
    def __init__(self, uid, area, years, tg_qu_values, rg_qu_values, total_population_values, urban_population_values,
                 rural_population_values, urbanization_rate_values, horizontal_years, indva, year1,
                 industry_method,icoefficient,p50,p75,p95,farmarea,year2,ucoe,forestarea,grassarea,fisharea,
                 big,small,greena,rla,eha,year3,FSFCoefficient,FFNQu,GNQu,fpnqu,bqu,squ,ucoe1,GreenQu,RLQu,EHQu,timet,indvqu=None,indvqu1=None):
        self.uid = uid #计算单元编号
        self.years = years #人口年份列表
        self.tg_qu_values = tg_qu_values   #城镇生活用水定额 列表数据 长度与水平年长度相同
        self.rg_qu_values = rg_qu_values   #农村生活用水定额 类型同上
        self.total_population_values = total_population_values #总人口 列表数据 长度与years长度相同
        self.urban_population_values = urban_population_values #城镇人口 同上
        self.rural_population_values = rural_population_values  #农村人口
        self.urbanization_rate_values = urbanization_rate_values #城镇化率
        self.horizontal_years = horizontal_years #水平年列表
        self.icoefficient = icoefficient #水平年对应的农田分配比率，字典数据，key为水平年整形数据，value为对应水平年的比例列表，列表长度根据timet决定是36还是12
        self.indva = indva#工业增加值，列表数据长度与years1相同
        self.indvqu = indvqu#万元工业增加值用水量（m³），同上
        self.year1 = year1#工业增加值对应的年份列表
        self.indvqu1 = indvqu1#水平年的万元工业增加值用水量，长度与水平年相同，列表数据
        self.industry_method = industry_method #选择工业数据计算方法 N或R，N为万元工业增加值用水量不预测，R为预测
        self.p50 = p50#P50%农田灌溉净定额（m³/667m²·a）长度与水平年相同，列表数据
        self.p75 = p75#p75 同上
        self.p95 = p95#p95 同上
        self.farmarea=farmarea #农田灌溉面积（h㎡）长度与year2相同，列表数据
        self.year2 = year2#农业，林牧面积，牲畜头数数据对应的年份
        self.ucoe=ucoe#农业灌溉水利用系数，长度与水平年相同，列表数据
        self.forestarea=forestarea#林果地灌溉面积（h㎡）
        self.grassarea=grassarea#草地灌溉面积（h㎡）
        self.big=big#大牲畜头数(万头)
        self.small=small#小牲畜头数(万只)
        self.fisharea=fisharea#鱼塘面积(h㎡)
        self.greena=greena#绿化面积（h㎡） 长度与year3相同
        self.rla=rla#河湖面积(h㎡)
        self.eha=eha#环卫面积(h㎡)
        self.FSFCoefficient=FSFCoefficient #水平年对应的林牧分配比率，字典数据，key为水平年整形数据，value为对应水平年的比例列表，列表长度根据timet决定是36还是12
        self.year3=year3#生态数据对应的年份
        self.ffnqu=FFNQu#林果地净定额（m³/h㎡），长度与水平年相同
        self.gnqu=GNQu#草地净定额（m³/h㎡） 同上
        self.fpnqu=fpnqu#鱼塘净定额（m³/（h㎡·a））同上
        self.bqu=bqu#大牲畜毛定额（L/（头·d））同上
        self.squ=squ#小牲畜毛定额（L/（只·d））同上
        self.ucoe1=ucoe1#林牧牲畜灌溉水利用系数 同上
        self.greenqu = GreenQu#绿化需水定额（m³/（㎡·a））同上
        self.rlqu=RLQu#河湖需水定额（万m³/（h㎡·a））同上
        self.ehqu=EHQu#环卫需水定额（m³/（㎡·a））同上
        self.timet = timet#判断月还是旬，'TEN-DAY'or 'MONTH'

        self.col=None
        self.predicted_values_dict = {}
        self.indurstry_results_dict = {}
        self.farm_dict={}
        self.forest_dict={}
        self.animals_dict={}
        self.river_dict={}

#月旬处理
    def len_col(self):
        if self.timet=='TEN-DAY':
            self.col=36
        elif self.timet=='MONTH':
            self.col=12
#计算平均增长率
    def calculate_average_growth_rate(self, values):
        first_value = values[0]
        last_value = values[-1]
        year_len = len(values)
        growth_rate = (last_value / first_value) ** (1 / (year_len - 1)) - 1
        return growth_rate
#计算平均降低率
    def calculate_average_decrease_rate(self, values):
        first_value = values[0]
        last_value = values[-1]
        year_len = len(values)
        decrease_rate = 1 - (last_value / first_value) ** (1 / (year_len - 1))
        return decrease_rate 
#通过平均增长率预测值，years_ahead表明年份之差
    def predict_value(self,values,growth_rate,years_ahead):
        last_value = values[-1]
        predicted_value = last_value * (1 + growth_rate) ** years_ahead
        return predicted_value
#生活蓄水量
    def predict_future_values(self):
        for years_ahead, tg_qu, rg_qu in zip(self.horizontal_years, self.tg_qu_values, self.rg_qu_values):
            average_total_population_growth_rate = self.calculate_average_growth_rate(self.total_population_values)
            predicted_population = self.predict_value(self.total_population_values,average_total_population_growth_rate,years_ahead - self.years[-1])
            average_urbanization_rate_growth_rate = self.calculate_average_growth_rate(self.urbanization_rate_values)
            predicted_urbanization_rate = min(self.predict_value(self.urbanization_rate_values,average_urbanization_rate_growth_rate,years_ahead - self.years[-1]), 1.0)
            urban_population_estimate = predicted_population*predicted_urbanization_rate
            rural_population_estimate = predicted_population - urban_population_estimate
            tg_vo = urban_population_estimate * tg_qu
            rg_vo = rural_population_estimate * rg_qu
            lg_vo = tg_vo+rg_vo
            average_tg_vo = tg_vo / self.col
            average_rg_vo = rg_vo / self.col
            average_lg_vo = lg_vo / self.col
            tgvopre = [average_tg_vo for i in range(self.col)]
            rgvopre = [average_rg_vo for i in range(self.col)]
            lgvopre = [average_lg_vo for i in range(self.col)]
            self.predicted_values_dict[years_ahead] = {
                        'predicted_population': predicted_population,
                        'predicted_urbanization_rate': predicted_urbanization_rate,
                        'predicted_urban_population': urban_population_estimate,
                        'predicted_rural_population': rural_population_estimate,
                        'TGVo': tg_vo,
                        'RGVo': rg_vo,
                        'LGVO': lg_vo,
                        'lgvopre':lgvopre
                    }

# 工业需水量预测,万元工业增加值用水量不进行预测，方法N
    def N(self):
        for years_ahead,idq in zip(self.horizontal_years,self.indvqu1):
            indva_growth_rate = self.calculate_average_growth_rate(self.indva)
            predicted_indva = self.predict_value(self.indva,indva_growth_rate,years_ahead - self.year1[-1])
            iv_n = predicted_indva*idq
            average_calculate = iv_n / self.col
            ivpre = [average_calculate for i in range(self.col)]
            self.indurstry_results_dict[years_ahead]={
                        'IndVAPre': predicted_indva,
                        'TIndGVoN': iv_n,
                        'TIndGVoNpre':ivpre
            }

# 工业需水量,万元工业增加值用水量,年均递减率模型R
# 单位换算：万元工业增加值用水量（m³），工业增加值（亿元），最终单位（万m³），不用换算。
    def R(self):
        for years_ahead in self.horizontal_years:
            indva_growth_rate = self.calculate_average_growth_rate(self.indva)
            indvqu_decrease_rate = self.calculate_average_decrease_rate(self.indvqu)
            ly = years_ahead - self.year1[-1]
            i = self.indva[-1] * (1 + indva_growth_rate) ** ly
            q_ir = self.indvqu[-1] * (1 - indvqu_decrease_rate) ** ly
            iv_r = q_ir * i
            average_calculate = iv_r / self.col
            ivpre = [average_calculate for i in range(self.col)]
            self.indurstry_results_dict[years_ahead] = {
                'IndVAPre': i,
                'IndVQuPre': q_ir,
                'TIndGVoR': iv_r,
                'TIndGVoRpre':ivpre
            }
#工业蓄水量调用方法
    def industry_calculate(self):
        if self.industry_method == 'R':
            self.R()
        elif self.industry_method == 'N':
            self.N()
# 农田灌溉需水
# 单位换算，定额单位为立方米/（亩·年），面积单位为hm²，最终水量单位为万立方米，换算时需除以667
    def predict_farm_values(self):
        if len(self.year2) == 1:
            for years_ahead,p50,p75,p95,ucoe in zip(self.horizontal_years,self.p50,self.p75,self.p95,self.ucoe):
                farm50 = self.farmarea[0] * p50 / 667
                farm75 = self.farmarea[0] * p75 / 667
                farm95 = self.farmarea[0] * p95 / 667
                farm50uco = farm50/ucoe
                farm75uco = farm75/ucoe
                farm95uco = farm95/ucoe

                f50 = [farm50uco*self.icoefficient[str(years_ahead)][i] for i in range(len(self.icoefficient[str(years_ahead)]))]
                f75 = [farm75uco*self.icoefficient[str(years_ahead)][i] for i in range(len(self.icoefficient[str(years_ahead)]))]
                f95 = [farm95uco*self.icoefficient[str(years_ahead)][i] for i in range(len(self.icoefficient[str(years_ahead)]))]
                self.farm_dict[years_ahead] = {
                    'P50INVo': farm50,
                    'P75INVo': farm75,
                    'P95INVo': farm95,
                    'P50IGVo': farm50uco,
                    'P75IGVo': farm75uco,
                    'P95IGVo': farm95uco,
                    'P50IGVopre': f50,
                    'P75IGVopre': f75,
                    'P95IGVopre': f95,
                }
        else:
            for years_ahead,p50,p75,p95,ucoe in zip(self.horizontal_years,self.p50,self.p75,self.p95,self.ucoe):
                farmarea_growth_rate = self.calculate_average_growth_rate(self.farmarea)
                predicted_area = self.predict_value(self.farmarea,farmarea_growth_rate,years_ahead - self.year2[-1])
                farm50 = predicted_area * p50 / 667
                farm75 = predicted_area * p75 / 667
                farm95 = predicted_area * p95 / 667
                farm50uco = farm50/ucoe
                farm75uco = farm75/ucoe
                farm95uco = farm95/ucoe
                f50 = [farm50uco*self.icoefficient[str(years_ahead)][i] for i in range(len(self.icoefficient[str(years_ahead)]))]
                f75 = [farm75uco*self.icoefficient[str(years_ahead)][i] for i in range(len(self.icoefficient[str(years_ahead)]))]
                f95 = [farm95uco*self.icoefficient[str(years_ahead)][i] for i in range(len(self.icoefficient[str(years_ahead)]))]
                self.farm_dict[years_ahead] = {
                    'P50INVo': farm50,
                    'P75INVo': farm75,
                    'P95INVo': farm95,
                    'P50IGVo': farm50uco,
                    'P75IGVo': farm75uco,
                    'P95IGVo': farm95uco,
                    'P50IGVopre': f50,
                    'P75IGVopre': f75,
                    'P95IGVopre': f95,
                }

# 林牧渔需水,包恬林果地灌溉、草场灌溉、鱼塘补水
# 面积（h㎡），定额（m³/h㎡），最终结果单位：万m³，单位换算乘以0.0001
    def predict_forest_values(self):
        if len(self.year2) == 1:
            for years_ahead,ffnqu,gnqu,fpnqu,ucoe1 in zip(self.horizontal_years,self.ffnqu,self.gnqu,self.fpnqu,self.ucoe1):
                ffnvo = self.forestarea[0] * ffnqu *0.0001
                gnvo = self.grassarea[0] * gnqu*0.0001
                fpnqu = self.fisharea[0] * fpnqu*0.0001
                fp = [ffnvo*self.FSFCoefficient[str(years_ahead)][i] for i in range(len(self.FSFCoefficient[str(years_ahead)]))]
                gp = [gnvo*self.FSFCoefficient[str(years_ahead)][i] for i in range(len(self.FSFCoefficient[str(years_ahead)]))]
                fpp = [fpnqu*self.FSFCoefficient[str(years_ahead)][i] for i in range(len(self.FSFCoefficient[str(years_ahead)]))]
                self.forest_dict[years_ahead] = {
                    'FFNVo': ffnvo,
                    'GNVo': gnvo,
                    'FPNVo': fpnqu,
                    'FFNVopre': fp,
                    'GNVopre': gp,
                    'FPNVopre': fpp,
                }
        else:
            for years_ahead,ffnqu,gnqu,fpnqu,ucoe1 in zip(self.horizontal_years,self.ffnqu,self.gnqu,self.fpnqu,self.ucoe1):
                forestarea_growth_rate = self.calculate_average_growth_rate(self.forestarea)
                predicted_forest_area = self.predict_value(self.forestarea,forestarea_growth_rate,years_ahead - self.year2[-1])
                grassarea_growth_rate = self.calculate_average_growth_rate(self.grassarea)
                predicted_grass_area = self.predict_value(self.grassarea,grassarea_growth_rate,years_ahead - self.year2[-1])
                fisharea_growth_rate = self.calculate_average_growth_rate(self.fisharea)
                predicted_fish_area = self.predict_value(self.fisharea,fisharea_growth_rate,years_ahead - self.year2[-1])
                ffnvo = predicted_forest_area * ffnqu*0.0001
                gnvo = predicted_grass_area * gnqu*0.0001
                fpnqu = predicted_fish_area * fpnqu*0.0001
                fp = [ffnvo*self.FSFCoefficient[str(years_ahead)][i] for i in range(len(self.FSFCoefficient[str(years_ahead)]))]
                gp = [gnvo*self.FSFCoefficient[str(years_ahead)][i] for i in range(len(self.FSFCoefficient[str(years_ahead)]))]
                fpp = [fpnqu*self.FSFCoefficient[str(years_ahead)][i] for i in range(len(self.FSFCoefficient[str(years_ahead)]))]
                self.forest_dict[years_ahead] = {
                    'FFNVo': ffnvo,
                    'GNVo': gnvo,
                    'FPNVo': fpnqu,
                    'FFNVopre': fp,
                    'GNVopre': gp,
                    'FPNVopre': fpp,
                }
#牲畜需水
# 单位换算(万头)和（L/（头·d）），最终结果为万立方米，需要乘以0.365
    def predict_animals_values(self):
        if len(self.year2) == 1:
            for years_ahead,bqu,squ,ucoe1 in zip(self.horizontal_years,self.bqu,self.squ,self.ucoe1):
                bvo = self.big[0] * bqu *0.365
                svo = self.small[0] * squ *0.365
                lvo =bvo+svo
                average_bg = bvo / self.col
                average_sg = svo / self.col
                average_lg = lvo /self.col
                bp = [average_bg for i in range(self.col)]
                sp = [average_sg for i in range(self.col)]
                lp= [ average_lg for i in range(self.col)]
                self.animals_dict[years_ahead] = {
                    'BLGvo': bvo,
                    'SLGvo': svo,
                    'LGvo': lvo,
                    'LGvopre': lp
                }
        else:
            for years_ahead,bqu,squ in zip(self.horizontal_years,self.bqu,self.squ):
                big_growth_rate = self.calculate_average_growth_rate(self.big)
                predicted_big_area = self.predict_value(self.big,big_growth_rate,years_ahead - self.year2[-1])
                small_growth_rate = self.calculate_average_growth_rate(self.small)
                predicted_small_area = self.predict_value(self.small,small_growth_rate,years_ahead - self.year2[-1])
                bvo = predicted_big_area * bqu *0.365
                svo = predicted_small_area * squ *0.365
                lvo =bvo+svo
                average_bg = bvo / self.col
                average_sg = svo / self.col
                average_lg = lvo /self.col
                bp = [average_bg for i in range(self.col)]
                sp = [average_sg for i in range(self.col)]
                lp= [ average_lg for i in range(self.col)]
                self.animals_dict[years_ahead] = {
                    'BLGvo': bvo,
                    'SLGvo': svo,
                    'LGvo': lvo,
                    'LGvopre': lp
                }

# 河道外生态需水,包括城镇生态环境需水模型和农村生态环境需水模型
# 单位换算：面积（h㎡），定额（m³/（㎡·a）），结果（万m³），无需换算
    def predict_river_values(self):
        if len(self.year3) == 1:
            for years_ahead,greenqu,rlqu,ehqu in zip(self.horizontal_years,self.greenqu,self.rlqu,self.ehqu):
                greenvo = self.greena[0] * greenqu
                rlvo = self.rla[0] * rlqu
                ehvo = self.eha[0] * ehqu
                outvo = greenvo+rlvo+ehvo
                average_green = greenvo / self.col
                average_rl = rlvo / self.col
                average_eh = ehvo / self.col
                average_out = outvo / self.col
                greenp = [average_green for i in range(self.col)]
                rlp = [average_rl for i in range(self.col)]
                ehp = [average_eh for i in range(self.col)]
                outp = [average_out for i in range(self.col)]
                self.river_dict[years_ahead] = {
                    'GreenVo': greenvo,
                    'RLVo': rlvo,
                    'EHVo': ehvo,
                    'OutREEVo': outvo,
                    'OutREEVopre':outp
                }
        else:
            for years_ahead,greenqu,rlqu,ehqu in zip(self.horizontal_years,self.greenqu,self.rlqu,self.ehqu):
                green_growth_rate = self.calculate_average_growth_rate(self.greena)
                predicted_green_area = self.predict_value(self.greena,green_growth_rate,years_ahead - self.year3[-1])
                rl_growth_rate = self.calculate_average_growth_rate(self.rla)
                predicted_rl_area = self.predict_value(self.rla,rl_growth_rate,years_ahead - self.year3[-1])
                eh_growth_rate = self.calculate_average_growth_rate(self.eha)
                predicted_eh_area = self.predict_value(self.eha,eh_growth_rate,years_ahead - self.year3[-1])
                greenvo = predicted_green_area * greenqu
                rlvo = predicted_rl_area * rlqu
                ehvo = predicted_eh_area * ehqu
                outvo = greenvo+rlvo+ehvo
                average_green = greenvo / self.col
                average_rl = rlvo / self.col
                average_eh = ehvo / self.col
                average_out = outvo / self.col
                greenp = [average_green for i in range(self.col)]
                rlp = [average_rl for i in range(self.col)]
                ehp = [average_eh for i in range(self.col)]
                outp = [average_out for i in range(self.col)]
                self.river_dict[years_ahead] = {
                    'GreenVo': greenvo,
                    'RLVo': rlvo,
                    'EHVo': ehvo,
                    'OutREEVo': outvo,
                    'OutREEVopre':outp
                }



